#!/data/data/com.termux/files/usr/bin/bash
#
# This script is a module of the 'termux-desktop' project.
# It handles the setup of the chroot/proot containers.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Author     : @sabamdarif
# License    : GPL-v3
# Description: setup the distro part of termux-desktop
# Repository : https://github.com/sabamdarif/termux-desktop

# shellcheck disable=SC2154
# shellcheck disable=SC2120
function check_termux() {
	if [[ -z "$PREFIX" && "$PREFIX" != *"/com.termux/"* ]]; then
		echo "${R}[${R}☓${R}]${R}${BOLD}Please run it inside termux${NC}"
		exit 0
	fi
}

function setup_proot_distro() {
	print_msg "${BOLD}Setting up ${C}proot-distro"
	package_install_and_check "proot-distro"
	banner
	print_msg "${BOLD}Setting up Selected Linux Distro: ${C}${selected_distro}"
	echo
	print_to_config "selected_distro"
	pd install "$selected_distro"
}

function check_su_access() {
	if command -v su >/dev/null 2>&1; then
		if su -c true >/dev/null 2>&1; then
			return 0
		fi
	fi
	return 1
}

function check_root_access() {
	if ! check_su_access; then
		return 1
	fi

	local whoami_out
	if whoami_out=$(su -c 'whoami' 2>/dev/null) && [ "$whoami_out" = "root" ]; then
		return 0
	fi
	return 1
}

function check_chroot_file() {
	if ! check_su_access; then
		return 1
	fi

	if su -c 'ls /system/bin/chroot-distro' >/dev/null 2>&1; then
		return 0
	fi
	return 1
}

function setup_chroot_distro() {
	print_msg "Checking if you have root access or not"
	package_install_and_check "sudo"
	local retry_count
	local max_retries
	retry_count=0
	max_retries=3
	while [ $retry_count -lt $max_retries ]; do
		if check_root_access; then
			print_success "Root access is enabled"
			break
		else
			((retry_count++))
			if [[ "$retry_count" -lt "$max_retries" ]]; then
				print_failed "Please grant root access to termux"
				print_msg "Want to check again (Attempt $retry_count/$max_retries)"
				wait_for_keypress
			else
				print_failed "Failed to get root access after $max_retries attempts"
				print_failed "Exiting..."
				exit 1
			fi
		fi
	done
	print_msg "Checking access to chroot-distro"
	retry_count=0
	while [ $retry_count -lt $max_retries ]; do
		if check_chroot_file; then
			print_success "chroot-distro binary exist"
			break
		else
			((retry_count++))

			if [ $retry_count -lt $max_retries ]; then
				print_failed "Cannot access /system/bin/chroot-distro file"
				print_msg "Please flash:- ${B}https://github.com/sabamdarif/chroot-distro"
				print_msg "Want to check again (Attempt $retry_count/$max_retries)"
				wait_for_keypress
			else
				print_failed "Failed to access chroot-distro after $max_retries attempts"
				print_msg "Exiting..."
				exit 1
			fi
		fi
	done
	print_msg "Creating a chroot-distro launcher..."
	cat <<-'EOF' >"$TERMUX_PREFIX/bin/chroot-distro"
		#!/data/data/com.termux/files/usr/bin/bash

		function check_su_access() {
		    if command -v su >/dev/null 2>&1; then
		        if su -c true >/dev/null 2>&1; then
		            return 0
		        fi
		    fi
		    return 1
		}

		function check_chroot_file() {
		    if ! check_su_access; then
		        return 1
		    fi

		    if su -c 'ls /system/bin/chroot-distro' >/dev/null 2>&1; then
		        return 0
		    fi
		    return 1
		}


		function wait_for_keypress() {
		    read -n1 -s -r -p " Press any key to continue, CTRL+c to cancel..."
		    echo
		}

		function checkup() {
		    local retry_count
		    local max_retries
		    retry_count=0
		    max_retries=3
		    while [ $retry_count -lt $max_retries ]; do
		        if check_chroot_file; then
		            break
		        else
		            ((retry_count++))
		            if [ $retry_count -lt $max_retries ]; then
		                echo "Cannot access /system/bin/chroot-distro file"
		                echo "Please flash:- ${B}https://github.com/sabamdarif/chroot-distro${NC}"
		                echo "Want to check again (Attempt $retry_count/$max_retries)"
		                wait_for_keypress
		            else
		                echo "Failed to access chroot-distro after $max_retries attempts"
		                echo "Exiting..."
		                exit 1
		            fi
		        fi
		    done
		}

		checkup

		# Fix: Use printf to properly escape arguments and pass them to su
		args=""
		for arg in "$@"; do
		    # Escape single quotes in arguments and wrap each argument in single quotes
		    escaped_arg=$(printf '%s' "$arg" | sed "s/'/'\\\\''/g")
		    args="$args '$escaped_arg'"
		done

		su -c "/system/bin/chroot-distro $args"
	EOF
	chmod +x "$TERMUX_PREFIX/bin/chroot-distro"
	chroot-distro install "$selected_distro"
	print_to_config "selected_distro"
}

function set_distro_paths {
	banner
	print_msg "Setiing up distro related paths"
	if [[ "$selected_distro_type" == "proot" ]]; then
		distro_path="$TERMUX_PREFIX/var/lib/proot-distro/installed-rootfs/$selected_distro"
	elif [[ "$selected_distro_type" == "chroot" ]]; then
		distro_path="/data/local/chroot-distro/installed-rootfs/$selected_distro"
	else
		print_failed "Unable to determine what distro type to use"
		print_msg "Fallback to:- proot-distro"
		selected_distro_type=proot
		distro_path="$TERMUX_PREFIX/var/lib/proot-distro/installed-rootfs/$selected_distro"
	fi
	save_path="$distro_path/root"
}

function setup_distro() {
	banner
	if [[ "$selected_distro_type" == "proot" ]]; then
		setup_proot_distro
	elif [[ "$selected_distro_type" == "chroot" ]]; then
		setup_chroot_distro
	fi
	print_to_config "selected_distro_type"
}

#########################################################################
#
# Update Distro | Install Required Packages | Add User | Fix audio issue
#
#########################################################################

function pd_package_install_and_check() {
	# Check for --root flag
	local use_sudo=true
	if [[ "$1" == "--root" ]]; then
		use_sudo=false
		shift
	fi

	# shellcheck disable=SC2206
	packs_list=($@)

	# Get distro id
	# shellcheck disable=SC1091
	if [ -f /etc/os-release ]; then
		. /etc/os-release
	fi

	# Install package
	for package_name in "${packs_list[@]}"; do
		print_msg "${BOLD}Installing package: ${C}$package_name"

		# Install package and handle errors
		install_failed=false
		if [[ "$ID" == "debian" ]] || [[ "$ID" == "ubuntu" ]]; then
			if $use_sudo; then
				if ! sudo apt install "$package_name" -y; then
					install_failed=true
				fi
			else
				if ! apt install "$package_name" -y; then
					install_failed=true
				fi
			fi
		elif [[ "$ID" == arch* ]]; then
			if $use_sudo; then
				if ! sudo pacman -Sy --noconfirm "$package_name"; then
					install_failed=true
				fi
			else
				if ! pacman -Sy --noconfirm "$package_name"; then
					install_failed=true
				fi
			fi
		elif [[ "$ID" == "fedora" ]]; then
			if $use_sudo; then
				if ! sudo dnf install "$package_name" -y; then
					install_failed=true
				fi
			else
				if ! dnf install "$package_name" -y; then
					install_failed=true
				fi
			fi
		fi

		# Handle error in installation
		if $install_failed; then
			print_failed "${BOLD} Error detected during installation of: ${C}$package_name${NC}"
			if [[ "$ID" == "debian" ]] || [[ "$ID" == "ubuntu" ]]; then
				if $use_sudo; then
					sudo apt --fix-broken install -y
					sudo dpkg --configure -a
					sudo apt install "$package_name" -y
				else
					apt --fix-broken install -y
					dpkg --configure -a
					apt install "$package_name" -y
				fi
			elif [[ "$ID" == arch* ]]; then
				if $use_sudo; then
					sudo pacman -Syu --noconfirm
					sudo pacman -Sy --noconfirm "$package_name"
				else
					pacman -Syu --noconfirm
					pacman -Sy --noconfirm "$package_name"
				fi
			elif [[ "$ID" == "fedora" ]]; then
				if $use_sudo; then
					sudo dnf --refresh install -y
					sudo rpm --rebuilddb
					sudo dnf install "$package_name" -y
				else
					dnf --refresh install -y
					rpm --rebuilddb
					dnf install "$package_name" -y
				fi
			fi
		fi

		# Reinstall if necessary
		if [[ "$ID" == "debian" ]] || [[ "$ID" == "ubuntu" ]]; then
			if ! dpkg -s "$package_name" >/dev/null 2>&1; then
				if $use_sudo; then
					sudo apt install "$package_name" -y
				else
					apt install "$package_name" -y
				fi
			fi
		elif [[ "$ID" == arch* ]]; then
			if ! pacman -Qi "$package_name" >/dev/null 2>&1; then
				if $use_sudo; then
					sudo pacman -Sy --noconfirm "$package_name"
				else
					pacman -Sy --noconfirm "$package_name"
				fi
			fi
		elif [[ "$ID" == "fedora" ]]; then
			if ! rpm -q "$package_name" >/dev/null 2>&1; then
				if $use_sudo; then
					sudo dnf install "$package_name" -y
				else
					dnf install "$package_name" -y
				fi
			fi
		fi

		# Check installation
		if [[ "$ID" == "debian" ]] || [[ "$ID" == "ubuntu" ]]; then
			if dpkg -s "$package_name" >/dev/null 2>&1; then
				print_success "$package_name ${G}installed successfully"
			else
				if command -v wget &>/dev/null || ls "$TERMUX_PREFIX/bin/"*"$package_name"* >/dev/null 2>&1; then
					print_success "$package_name ${G}installed successfully"
				fi
			fi
		elif [[ "$ID" == arch* ]]; then
			if pacman -Qi "$package_name" >/dev/null 2>&1; then
				print_success "$package_name ${G}installed successfully"
			else
				if command -v wget &>/dev/null || ls "$TERMUX_PREFIX/bin/"*"$package_name"* >/dev/null 2>&1; then
					print_success "$package_name ${G}installed successfully"
				fi
			fi
		elif [[ "$ID" == "fedora" ]]; then
			if rpm -q "$package_name" >/dev/null 2>&1; then
				print_success "$package_name ${G}installed successfully"
			else
				if command -v wget &>/dev/null || ls "$TERMUX_PREFIX/bin/"*"$package_name"* >/dev/null 2>&1; then
					print_success "$package_name ${G}installed successfully"
				fi
			fi
		fi
	done
	echo ""
}

#############################
# Create Shell Setup Script #
#############################

function create_shell_script() {
	local script_path="$1"
	local shell_setup_content="$2"
	# Create directory if it doesn't exist
	if [[ "$selected_distro_type" == "chroot" ]]; then
		sudo mkdir -p "$(dirname "$script_path")"
	else
		mkdir -p "$(dirname "$script_path")"
	fi

	if [[ "$selected_distro_type" == "chroot" ]]; then
		sudo tee "$script_path" >/dev/null <<-EOF
			#!/data/data/com.termux/files/usr/bin/bash

			# Repository URLs
			readonly REPO_OWNER="$REPO_OWNER"
			readonly REPO_NAME="$REPO_NAME"
			readonly REPO_BRANCH_MAIN="$REPO_BRANCH_MAIN"
			readonly REPO_SETUP_FILE_BRANCH="$REPO_SETUP_FILE_BRANCH"
			readonly REPO_SETUP_FILES_FOLDER="$REPO_SETUP_FILES_FOLDER"
			readonly REPO_RAW_URL="$REPO_RAW_URL"
			readonly TERMUX_HOME="$TERMUX_HOME"
			readonly TERMUX_PREFIX="$TERMUX_PREFIX"
			# Retry configuration
			readonly MAX_DOWNLOAD_RETRIES="$MAX_DOWNLOAD_RETRIES"
			readonly MAX_INSTALL_RETRIES="$MAX_INSTALL_RETRIES"
			readonly DOWNLOAD_TIMEOUT="$DOWNLOAD_TIMEOUT"

			#########################################################################
			#
			# Initial Values
			#
			#########################################################################
			readonly TERMUX_DESKTOP_PATH="$TERMUX_DESKTOP_PATH"
			readonly CONFIG_FILE="$CONFIG_FILE"
			readonly LOG_FILE="$LOG_FILE"
			LITE_MODE="$LITE_MODE"
			#########################################################################
			#
			# Color Setup
			#
			#########################################################################
			# shellcheck disable=SC2154
			R="$R"
			G="$G"
			Y="$Y"
			B="$B"
			C="$C"
			NC="$NC"
			BOLD="$BOLD"
		EOF
	else
		cat <<-EOF >"$script_path"
			#!/data/data/com.termux/files/usr/bin/bash

			# Repository URLs
			readonly REPO_OWNER="$REPO_OWNER"
			readonly REPO_NAME="$REPO_NAME"
			readonly REPO_BRANCH_MAIN="$REPO_BRANCH_MAIN"
			readonly REPO_SETUP_FILE_BRANCH="$REPO_SETUP_FILE_BRANCH"
			readonly REPO_SETUP_FILES_FOLDER="$REPO_SETUP_FILES_FOLDER"
			readonly REPO_RAW_URL="$REPO_RAW_URL"
			readonly TERMUX_HOME="$TERMUX_HOME"
			readonly TERMUX_PREFIX="$TERMUX_PREFIX"
			# Retry configuration
			readonly MAX_DOWNLOAD_RETRIES="$MAX_DOWNLOAD_RETRIES"
			readonly MAX_INSTALL_RETRIES="$MAX_INSTALL_RETRIES"
			readonly DOWNLOAD_TIMEOUT="$DOWNLOAD_TIMEOUT"

			#########################################################################
			#
			# Initial Values
			#
			#########################################################################
			readonly TERMUX_DESKTOP_PATH="$TERMUX_DESKTOP_PATH"
			readonly CONFIG_FILE="$CONFIG_FILE"
			readonly LOG_FILE="$LOG_FILE"
			LITE_MODE="$LITE_MODE"
			#########################################################################
			#
			# Color Setup
			#
			#########################################################################
			# shellcheck disable=SC2154
			R="$R"
			G="$G"
			Y="$Y"
			B="$B"
			C="$C"
			NC="$NC"
			BOLD="$BOLD"
		EOF
	fi
	if [[ "$selected_distro_type" == "chroot" ]]; then
		typeset -f check_termux log_debug print_success print_failed print_warn print_msg wait_for_keypress check_and_create_directory check_and_delete check_and_backup download_file check_and_restore detect_package_manager package_install_and_check package_check_and_remove get_file_name_number extract_zip_with_progress extract_archive download_and_extract count_subfolders confirmation_y_or_n get_latest_release install_font_for_style select_an_option read_conf print_to_config pd_package_install_and_check set_distro_paths setup_distro | sudo tee -a "$script_path" >/dev/null
		echo "$shell_setup_content" | sudo tee -a "$script_path" >/dev/null
	else
		typeset -f check_termux log_debug print_success print_failed print_warn print_msg wait_for_keypress check_and_create_directory check_and_delete check_and_backup download_file check_and_restore detect_package_manager package_install_and_check package_check_and_remove get_file_name_number extract_zip_with_progress extract_archive download_and_extract count_subfolders confirmation_y_or_n get_latest_release install_font_for_style select_an_option read_conf print_to_config pd_package_install_and_check set_distro_paths setup_distro >>"$script_path"
		echo "$shell_setup_content" >>"$script_path"
	fi
	# Make script executable
	if [[ "$selected_distro_type" == "chroot" ]]; then
		sudo chmod +x "$script_path"
	else
		chmod +x "$script_path"
	fi
	# Verify script was created
	if [[ "$selected_distro_type" == "chroot" ]]; then
		if ! su -c "ls '$script_path'" >/dev/null 2>&1; then
			print_failed "Failed to create script at $script_path"
		fi
	else
		if [[ ! -f "$script_path" ]]; then
			print_failed "Failed to create script at $script_path"
		fi
	fi
}

#################
# Update distro #
#################
function update_distro_repo() {
	print_msg "${BOLD}Updating $selected_distro And Installing Required Packages"
	echo
	if [[ "$selected_distro" == "debian" ]] || [[ "$selected_distro" == "ubuntu" ]]; then
		"${selected_distro_type}"-distro login "$selected_distro" --shared-tmp -- env DISPLAY=:"$display_number" apt update
		"${selected_distro_type}"-distro login "$selected_distro" --shared-tmp -- env DISPLAY=:"$display_number" apt upgrade -y -o Dpkg::Options::="--force-confnew"
		"${selected_distro_type}"-distro login "$selected_distro" --shared-tmp -- env DISPLAY=:"$display_number" apt install sudo apt-file -y
	elif [[ "$selected_distro" == "archlinux" ]]; then
		"${selected_distro_type}"-distro login "$selected_distro" --shared-tmp -- env DISPLAY=:"$display_number" pacman -Syu --noconfirm
		"${selected_distro_type}"-distro login "$selected_distro" --shared-tmp -- env DISPLAY=:"$display_number" pacman -S --noconfirm sudo
	elif [[ "$selected_distro" == "fedora" ]]; then
		"${selected_distro_type}"-distro login "$selected_distro" -- /bin/bash -c "echo 'max_parallel_downloads=10' >> '/etc/dnf/dnf.conf'"
		"${selected_distro_type}"-distro login "$selected_distro" -- /bin/bash -c "echo 'fastestmirror=True/' >> '/etc/dnf/dnf.conf'"
		"${selected_distro_type}"-distro login "$selected_distro" --shared-tmp -- env DISPLAY=:"$display_number" dnf update -y
		"${selected_distro_type}"-distro login "$selected_distro" --shared-tmp -- env DISPLAY=:"$display_number" dnf upgrade -y
		"${selected_distro_type}"-distro login "$selected_distro" --shared-tmp -- env DISPLAY=:"$display_number" dnf install sudo -y
	fi
	if [[ "$selected_distro_type" == "proot" ]]; then
		chmod -R +w "$distro_path/"
	fi
}

###################
# Setup time zone #
###################
function set_distro_time_zone() {
	timezone=$(getprop persist.sys.timezone)
	"${selected_distro_type}"-distro login "$selected_distro" --shared-tmp -- env DISPLAY=:"$display_number" rm /etc/localtime
	"${selected_distro_type}"-distro login "$selected_distro" --shared-tmp -- env DISPLAY=:"$display_number" cp "/usr/share/zoneinfo/$timezone" /etc/localtime
}

###################
# Fix Sound Issue #
###################
function distro_fix_sound_issue() {
	banner
	print_msg "${BOLD}Fixing ${selected_distro_type} distro Sound Problem..."
	echo
	audio_related_packs="pulseaudio"
	install_audio_related_packs=$(
		cat <<-EOF
			pd_package_install_and_check "$audio_related_packs"
			check_and_delete "install_audio_related_packs.sh"
		EOF
	)
	create_shell_script "$save_path/install_audio_related_packs.sh" "$install_audio_related_packs"
	"${selected_distro_type}"-distro login "$selected_distro" -- /bin/bash -c 'bash /root/install_audio_related_packs.sh'
	if [[ "$selected_distro_type" == "chroot" ]]; then
		echo "export PULSE_SERVER=127.0.0.1" | sudo tee -a "$distro_path/etc/profile" >/dev/null
	else
		echo "export PULSE_SERVER=127.0.0.1" >>"$distro_path/etc/profile"
	fi
	print_to_config "pd_audio_config_answer"
}

###########################################
# create a user account inside the distro #
###########################################
function distro_setup_user() {
	# set user name value
	if [[ "$pd_useradd_answer" == "n" ]]; then
		final_user_name="root"
	elif [[ "$pd_useradd_answer" == "y" ]]; then
		final_user_name="${user_name}"
	fi
	print_to_config "pd_useradd_answer"
	print_to_config "user_name"

	# set password value
	if [[ "$pd_pass_type" == "2" ]]; then
		final_pass="${pass}"
	else
		final_pass="root"
	fi
	print_to_config "pd_pass_type"
	print_to_config "pass"

	if [[ "$pd_useradd_answer" == "y" ]]; then
		# first setup the user
		"${selected_distro_type}"-distro login "$selected_distro" -- /bin/sh -c 'groupadd storage'
		"${selected_distro_type}"-distro login "$selected_distro" -- /bin/sh -c 'groupadd wheel'
		"${selected_distro_type}"-distro login "$selected_distro" -- /bin/sh -c "useradd -m -g users -s \$(which bash) ${final_user_name}"
		"${selected_distro_type}"-distro login "$selected_distro" -- /bin/sh -c "usermod -aG wheel,polkitd,audio,video,storage ${final_user_name}"
		"${selected_distro_type}"-distro login "$selected_distro" -- /bin/sh -c "echo '${final_user_name}:${final_pass}' | chpasswd"

		# setup user without password confirmation
		if [[ "$pd_pass_type" == "1" ]]; then
			"${selected_distro_type}"-distro login "$selected_distro" -- /bin/sh -c "chmod u+rw /etc/sudoers"
			"${selected_distro_type}"-distro login "$selected_distro" -- /bin/sh -c "echo '$final_user_name ALL=(ALL) NOPASSWD:ALL' | tee -a /etc/sudoers > /dev/null 2>&1"
			"${selected_distro_type}"-distro login "$selected_distro" -- /bin/sh -c "chmod u-w /etc/sudoers"
			"${selected_distro_type}"-distro login "$selected_distro" -- /bin/sh -c 'sudo -k'
		# setup user with password
		elif [[ "$pd_pass_type" == "2" ]]; then
			"${selected_distro_type}"-distro login "$selected_distro" -- /bin/sh -c "chmod u+rw /etc/sudoers"
			"${selected_distro_type}"-distro login "$selected_distro" -- /bin/sh -c "echo '$final_user_name ALL=(ALL:ALL) ALL' | tee -a /etc/sudoers > /dev/null 2>&1"
			"${selected_distro_type}"-distro login "$selected_distro" -- /bin/sh -c "chmod u-w /etc/sudoers"
			"${selected_distro_type}"-distro login "$selected_distro" -- /bin/sh -c 'sudo -k'

		fi

	fi
}

function distro_basic_task() {
	banner
	update_distro_repo
	set_distro_time_zone
	distro_fix_sound_issue
	distro_setup_user
}

#########################################################################
#
# Setup Zsh And Terminal Utility
#
#########################################################################

#############
# ZSH Setup #
#############
function distro_zsh_setup() {
	if [[ "$chosen_shell_name" == "zsh" ]]; then
		zsh_setup_content=$(
			cat <<-EOF
				pd_package_install_and_check "git zsh wget"

				if [[ "$selected_distro" == "debian" ]] || [[ "$selected_distro" == "ubuntu" ]]; then
				chsh -s /usr/bin/zsh ${final_user_name}
				else
				chsh -s /bin/zsh ${final_user_name}
				fi
				check_and_delete "pd_zsh_install.sh"
			EOF
		)
		create_shell_script "$distro_path/root/pd_zsh_install.sh" "$zsh_setup_content"
		banner
		print_msg "${BOLD}Setting up shell for ${selected_distro}..."
		echo
		"${selected_distro_type}"-distro login "$selected_distro" -- /bin/bash -c 'bash /root/pd_zsh_install.sh'
	fi
}

##########################
# Terminal Utility Setup #
##########################
function distro_terminal_utility_setup() {
	if [[ "$terminal_utility_setup_answer" == "y" ]]; then

		if [[ "$selected_distro" == "debian" ]] || [[ "$selected_distro" == "ubuntu" ]]; then
			terminal_utility_content=$(
				cat <<-'EOF'
					pd_package_install_and_check "zoxide bat wget gpg fzf eza fastfetch nala"
					check_and_delete "pd_setup.sh"
				EOF
			)
		else
			terminal_utility_content=$(
				cat <<-'EOF'
					pd_package_install_and_check "zoxide bat wget gpg eza fastfetch fzf"
					check_and_delete "pd_setup.sh"
				EOF
			)
		fi
		create_shell_script "$save_path/pd_setup.sh" "$terminal_utility_content"
		banner
		print_msg "Configuring Terminal Utility For ${selected_distro}..."
		echo
		"${selected_distro_type}"-distro login --user "$final_user_name" "$selected_distro" -- /bin/bash -c 'bash /root/pd_setup.sh'
	fi
}

#########################################################################
#
# Create App Installer Shortcut
#
#########################################################################
function add_installer_common() {

	cat <<-EOF >"$TERMUX_PREFIX/bin/$selected_distro"
		#!/data/data/com.termux/files/usr/bin/bash

		source $TERMUX_PREFIX/etc/termux-desktop/common_functions

		xhost + >/dev/null 2>&1
		# --- USB auto-bind helpers ---
		usb_mounts() {
		  # Candidate external filesystems under /mnt/media_rw/<UUID>
		  local candidates seen="" media uuid acc
		  candidates=\$(awk '(\$2 ~ "^/mnt/media_rw/[0-9A-Fa-f-]+\$") && (\$3 ~ /vfat|exfat|ntfs|fuseblk/) {print \$2}' /proc/mounts | sort -u)
		  while IFS= read -r media; do
		    [ -d "\$media" ] || continue
		    uuid="\${media##*/}"
		    acc="/storage/\${uuid}"; [ -r "\$acc" ] || acc="\$media"
		    [ -r "\$acc" ] || continue
		    case ",\$seen," in *",\$uuid,"*) ;; *) printf '%s\n' "\$acc"; seen="\${seen},\${uuid}";; esac
		  done <<< "\$candidates"
		}

		urldecode() { local s="\${1//+/ }"; printf '%b' "\${s//%/\\x}"; }

		normalize_arg() {
		  # Decode file:// and %XX to the real path (do not rewrite the path itself)
		  local a="$1"
		  case "\$a" in file://*) a="\${a#file://}";; esac
		  if [[ "\$a" == *%* || "\$a" == *+* ]]; then a="\$(urldecode "\$a")"; fi
		  echo "\$a"
		}

		enum_media=0

		usb_bind_args() {
		  if [ -n "\${PDRUN_DISABLE_USB_BIND:-}" ]; then printf ''; return 0; fi
		  local args="--bind /storage:/storage --bind /mnt/media_rw:/mnt/media_rw"

		  # Convenience bind (/mnt/usb/<UUID>)
		  local list; if [ -n "\${PDRUN_USB_BIND_PATH:-}" ]; then list="\${PDRUN_USB_BIND_PATH}"; else list="\$(usb_mounts 2>/dev/null)"; fi
		  if [ -n "\$list" ]; then
		    local include="\${PDRUN_USB_INCLUDE:-}"; local exclude="\${PDRUN_USB_EXCLUDE:-}"; local limit="\${PDRUN_USB_LIMIT:-0}"
		    local count=0
		    while IFS= read -r p; do
		      [ -n "\$p" ] || continue
		      local uuid="\${p##*/}"
		      if [ -n "\$include" ]; then case ",\$include," in *",\$uuid,"*) ;; *) continue;; esac; fi
		      if [ -n "\$exclude" ]; then case ",\$exclude," in *",\$uuid,"*) continue;; esac; fi
		      if [ "\$limit" -gt 0 ] && [ "\$count" -ge "\$limit" ]; then break; fi
		      args="\${args} --bind \${p}:/mnt/usb/\${uuid}"
		      count=\$((count+1))
		    done <<< "\$list"
		  fi

		  # If needed: self-bind individual paths (to prevent /mnt/media_rw from being omitted in file dialogs)
		  if [ "\${enum_media:-0}" -eq 1 ] || [[ "\${PDRUN_MEDIA_RW_ENUM:-}" =~ ^(1|true|yes)$ ]]; then
		    while IFS= read -r p; do
		      [ -n "\$p" ] || continue
		      args="\${args} --bind \${p}:\${p}"                    # /mnt/media_rw/<UUID>
		      uuid="\${p##*/}"; st="/storage/\${uuid}"
		      [ -r "\$st" ] && args="\${args} --bind \${st}:\${st}"  # /storage/<UUID>
		    done <<<"\$(usb_mounts 2>/dev/null | sed -E 's|^/storage/([0-9A-Fa-f-]+)$|/mnt/media_rw/\\1|')"
		  fi

		  printf '%s' "\$args"
		}
		if [ "\$#" -eq 0 ]; then
		    if [ "\$PWD" = "$TERMUX_HOME" ]; then
		        ${selected_distro_type}-distro login \$(usb_bind_args) --user "$final_user_name" "$selected_distro" --shared-tmp $termux_home_link
		    else
		        ${selected_distro_type}-distro login \$(usb_bind_args) --user "$final_user_name" "$selected_distro" --shared-tmp --work-dir "\$PWD" $termux_home_link
		    fi

		    check_and_create_directory "$TERMUX_PREFIX/share/applications/pd_added"
		fi
	EOF
}

#######################################################
################ Debian Distro Command ################
#######################################################

function proot_distro_debian_based_app_installer() {

	cat <<-TOP_EOF >>"$TERMUX_PREFIX/bin/$selected_distro"
		package_install_and_add_to_menu() {
		    #################################################
		    ## Handle install package and add to menu part ##
		    #################################################

		    # Create the packinstall.sh script
		    cat <<'EOF' >"${save_root_path}/packinstall.sh"
		#!/bin/bash

		source $TERMUX_PREFIX/etc/termux-desktop/common_functions

		# First configure dpkg and update apt
		dpkg --configure -a
		apt update
		apt-file update

		# Install the packages - get arguments directly
		apt install "\$@"

		# Process desktop files for non-option arguments
		for arg in "\$@"; do
		    # Skip options (starting with -)
		    if [[ "\$arg" != -* ]]; then
		        package_name="\$arg"

		        # Find desktop files for this package
		        echo "\${R}[\${C}-\${R}]\${G} Searchling for .desktop file… \${W}"
		        echo
		        desktop_files=\$(dpkg-query -W -f='\${binary:Package}\n' | grep "^\$package_name\(-.*\)\?\$" | xargs dpkg-query -L | grep "^/usr/share/applications/.*\.desktop\$")
		        # If not found
		        if [ -z "\$desktop_files" ]; then
		            if ! apt-file list "\$package_name" >/dev/null 2>&1; then
		                echo "\${R}[\${C}-\${R}]\${G} Updating apt-file cache… \${W}"
		                apt-file update
		            fi

		            if command -v apt-file >/dev/null; then
		                desktop_files=\$(apt-file list "\$package_name" | awk -F': ' -v pkg="\$package_name" '\$1 == pkg && \$2 ~ /\.desktop\$/ { print \$2 }')
		            fi
		            if [ -z "\$desktop_files" ]; then
		                print_failed "No .desktop files found for package \${C} \$package_name \${R}/usr/share/applications."
		            fi
		        else
		            for desktop_files_name in \$desktop_files; do
		                desktop_files_with_ext=\$(basename "\$desktop_files_name")
		                desktop_files_without_ext="\${desktop_files_with_ext%.desktop}"
		                if dpkg -s "\$package_name" >/dev/null 2>&1; then
		                    print_success "Adding \${C}\${desktop_files_without_ext} \${G}To Termux Menu"
		                    cp "/usr/share/applications/\${desktop_files_with_ext}" "$TERMUX_PREFIX/share/applications/pd_added/"
		                    sed -i 's/Exec=/Exec=pdrun /g' "$TERMUX_PREFIX/share/applications/pd_added/\${desktop_files_with_ext}"
		                fi
		            done
		        fi
		    fi
		done
		check_and_delete 'packinstall.sh'
		EOF
		    # Make the script executable
		    proot-distro login "${selected_distro}" --shared-tmp -- /bin/bash -c "chmod +x /root/packinstall.sh"
		    # Execute the script with all arguments
		    proot-distro login "${selected_distro}" --shared-tmp -- /bin/bash -c "export DISPLAY=:${display_number}; export XDG_RUNTIME_DIR=${TMPDIR}; bash /root/packinstall.sh \$*"
		}

		package_uninstall_and_remove_from_menu() {
		    ###################################################
		    # Handle remove package and remove from menu part #
		    ###################################################
		    # Create the packremove.sh script
		    cat <<'EOF' >"${save_root_path}/packremove.sh"
		#!/bin/bash

		source $TERMUX_PREFIX/etc/termux-desktop/common_functions

		# Get the removal command (remove or autoremove)
		removal_command="\$1"
		shift

		# Process each non-option argument (package)
		for arg in "\$@"; do
		    # Skip options
		    if [[ "\$arg" == -* ]]; then
		        continue
		    fi

		    package_name="\$arg"
		    desktop_files=""

		    # Find desktop files for this package
		    echo "\${R}[\${C}-\${R}]\${G} Searchling for .desktop file… \${W}"
		    echo
		     desktop_files=\$(dpkg-query -W -f='\${binary:Package}\n' | grep "^\$package_name\(-.*\)\?\$" | xargs dpkg-query -L | grep "^/usr/share/applications/.*\.desktop\$" || true)
		    # If not found
		    if [[ -z "\$desktop_files" ]]; then
		        if command -v apt-file >/dev/null; then
		            if ! apt-file list "\$package_name" >/dev/null 2>&1; then
		                echo "\${R}[\${C}-\${R}]\${G} Updating apt-file cache… \${W}"
		                apt-file update
		            fi
		        desktop_files=\$(apt-file list "\$package_name" | awk -F': ' -v pkg="\$package_name" '\$1 == pkg && \$2 ~ /\.desktop\$/ { print \$2 }')
		        fi
		    fi

		    # Remove the package
		    echo "\${R}[\${C}-\${R}]\${G} Removing packages...\${W}"
		    echo
		    apt "\$removal_command" "\$package_name"

		    # Handle desktop files
		    if [[ -z "\$desktop_files" ]]; then
		        print_failed "No .desktop files found for package \${C}\$package_name\${R} /usr/share/applications"
		    else
		        for desktop_files_name in \$desktop_files; do
		            desktop_files_with_ext=\$(basename "\$desktop_files_name")
		            desktop_files_without_ext="\${desktop_files_with_ext%.desktop}"

		            # Check if package is really uninstalled
		            if ! dpkg -s "\$package_name" >/dev/null 2>&1; then
		                print_success "Removing \${C}\${desktop_files_without_ext} \${G}From Termux Menu"
		                check_and_delete "$TERMUX_PREFIX/share/applications/pd_added/\${desktop_files_with_ext}"
		            else
		                print_failed "Package \${C}\$package_name\${R} is still installed; skipping desktop removal."
		            fi
		        done
		    fi

		done

		check_and_delete 'packremove.sh'
		EOF

		    # Make the script executable
		    proot-distro login "${selected_distro}" --shared-tmp -- /bin/bash -c "chmod +x /root/packremove.sh"

		    # Execute the script with all arguments
		    proot-distro login "${selected_distro}" --shared-tmp -- /bin/bash -c "export DISPLAY=:${display_number}; export XDG_RUNTIME_DIR=$TERMUX_PREFIX/tmp; bash /root/packremove.sh \$1 \${*:2}"

		}

		update_distro() {
		    #################################################
		    ############### Handle update part ##############
		    #################################################
		    proot-distro login --user "$final_user_name" "$selected_distro" --shared-tmp --termux-home -- env DISPLAY=:"$display_number" sudo apt update
		    proot-distro login --user "$final_user_name" "$selected_distro" --shared-tmp --termux-home -- env DISPLAY=:"$display_number" sudo apt-file update
		}
	TOP_EOF
}

function chroot_distro_debian_based_app_installer() {
	cat <<-TOP_EOF >>"$TERMUX_PREFIX/bin/$selected_distro"
		package_install_and_add_to_menu() {
		    #################################################
		    ## Handle install package and add to menu part ##
		    #################################################

		    # Create the packinstall.sh script
		    sudo tee "${save_root_path}/packinstall.sh" >/dev/null <<'EOF'
		#!/bin/bash

		source $TERMUX_PREFIX/etc/termux-desktop/common_functions

		# First configure dpkg and update apt
		dpkg --configure -a
		apt update
		apt-file update

		# Install the packages - get arguments directly
		apt install "\$@"

		# Process desktop files for non-option arguments
		for arg in "\$@"; do
		    # Skip options (starting with -)
		    if [[ "\$arg" != -* ]]; then
		        package_name="\$arg"

		        # Find desktop files for this package
		        echo "\${R}[\${C}-\${R}]\${G} Searchling for .desktop file… \${W}"
		        echo
		        desktop_files=\$(dpkg-query -W -f='\${binary:Package}\n' | grep "^\$package_name\(-.*\)\?\$" | xargs dpkg-query -L | grep "^/usr/share/applications/.*\.desktop\$")
		        # If not found
		        if [ -z "\$desktop_files" ]; then
		            if ! apt-file list "\$package_name" >/dev/null 2>&1; then
		                echo "\${R}[\${C}-\${R}]\${G} Updating apt-file cache… \${W}"
		                apt-file update
		            fi

		            if command -v apt-file >/dev/null; then
		                desktop_files=\$(apt-file list "\$package_name" | awk -F': ' -v pkg="\$package_name" '\$1 == pkg && \$2 ~ /\.desktop\$/ { print \$2 }')
		            fi
		            if [ -z "\$desktop_files" ]; then
		                print_failed "No .desktop files found for package \${C} \$package_name \${R}/usr/share/applications."
		            fi
		        else
		            for desktop_files_name in \$desktop_files; do
		                desktop_files_with_ext=\$(basename "\$desktop_files_name")
		                desktop_files_without_ext="\${desktop_files_with_ext%.desktop}"
		                if dpkg -s "\$package_name" >/dev/null 2>&1; then
		                    print_success "Adding \${C}\${desktop_files_without_ext} \${G}To Termux Menu"
		                    cp "/usr/share/applications/\${desktop_files_with_ext}" "$TERMUX_PREFIX/share/applications/pd_added/"
		                    sed -i 's/Exec=/Exec=pdrun /g' "$TERMUX_PREFIX/share/applications/pd_added/\${desktop_files_with_ext}"
		                fi
		            done
		        fi
		    fi
		done
		check_and_delete 'packinstall.sh'
		EOF
		    # Make the script executable
		    chroot-distro login "${selected_distro}" --shared-tmp -- /bin/bash -c "chmod +x /root/packinstall.sh"
		    # Execute the script with all arguments
		    chroot-distro login "${selected_distro}" --shared-tmp -- /bin/bash -c "export DISPLAY=:${display_number}; export XDG_RUNTIME_DIR=${TMPDIR}; bash /root/packinstall.sh \$*"

		}

		package_uninstall_and_remove_from_menu() {
		    ###################################################
		    # Handle remove package and remove from menu part #
		    ###################################################
		    # Create the packremove.sh script
		    sudo tee "${save_root_path}/packremove.sh" >/dev/null <<'EOF'
		#!/bin/bash

		source $TERMUX_PREFIX/etc/termux-desktop/common_functions

		# Get the removal command (remove or autoremove)
		removal_command="\$1"
		shift

		# Process each non-option argument (package)
		for arg in "\$@"; do
		    # Skip options
		    if [[ "\$arg" == -* ]]; then
		        continue
		    fi

		    package_name="\$arg"
		    desktop_files=""

		    # Find desktop files for this package
		    echo "\${R}[\${C}-\${R}]\${G} Searchling for .desktop file… \${W}"
		    echo
		     desktop_files=\$(dpkg-query -W -f='\${binary:Package}\n' | grep "^\$package_name\(-.*\)\?\$" | xargs dpkg-query -L | grep "^/usr/share/applications/.*\.desktop\$" || true)
		    # If not found
		    if [[ -z "\$desktop_files" ]]; then
		        if command -v apt-file >/dev/null; then
		            if ! apt-file list "\$package_name" >/dev/null 2>&1; then
		                echo "\${R}[\${C}-\${R}]\${G} Updating apt-file cache… \${W}"
		                apt-file update
		            fi
		        desktop_files=\$(apt-file list "\$package_name" | awk -F': ' -v pkg="\$package_name" '\$1 == pkg && \$2 ~ /\.desktop\$/ { print \$2 }')
		        fi
		    fi

		    # Remove the package
		    echo "\${R}[\${C}-\${R}]\${G} Removing packages...\${W}"
		    echo
		    apt "\$removal_command" "\$package_name"

		    # Handle desktop files
		    if [[ -z "\$desktop_files" ]]; then
		        print_failed "No .desktop files found for package \${C}\$package_name\${R} /usr/share/applications"
		    else
		        for desktop_files_name in \$desktop_files; do
		            desktop_files_with_ext=\$(basename "\$desktop_files_name")
		            desktop_files_without_ext="\${desktop_files_with_ext%.desktop}"

		            # Check if package is really uninstalled
		            if ! dpkg -s "\$package_name" >/dev/null 2>&1; then
		                print_success "Removing \${C}\${desktop_files_without_ext} \${G}From Termux Menu"
		                check_and_delete "$TERMUX_PREFIX/share/applications/pd_added/\${desktop_files_with_ext}"
		            else
		                print_failed "Package \${C}\$package_name\${R} is still installed; skipping desktop removal."
		            fi
		        done
		    fi

		done

		check_and_delete 'packremove.sh'
		EOF

		    # Make the script executable
		    chroot-distro login "${selected_distro}" --shared-tmp -- /bin/bash -c "chmod +x /root/packremove.sh"
		    # Execute the script with all arguments
		    chroot-distro login "${selected_distro}" --shared-tmp -- /bin/bash -c "export DISPLAY=:${display_number}; export XDG_RUNTIME_DIR=$TERMUX_PREFIX/tmp; bash /root/packremove.sh \$1 \${*:2}"

		}

		update_distro() {
		    #################################################
		    ############### Handle update part ##############
		    #################################################
		    chroot-distro login --user "$final_user_name" "$selected_distro" --shared-tmp -- env DISPLAY=:"$display_number" sudo apt update
		    chroot-distro login --user "$final_user_name" "$selected_distro" --shared-tmp -- env DISPLAY=:"$display_number" sudo apt-file update

		}
	TOP_EOF

}

function debian_based_app_installer() {
	if [[ "$selected_distro_type" == "chroot" ]]; then
		chroot_distro_debian_based_app_installer
	else
		proot_distro_debian_based_app_installer
	fi
}

#######################################################
################# Arch Distro Command #################
#######################################################
function proot_distro_arch_based_app_installer() {

	cat <<-TOP_EOF >>"$TERMUX_PREFIX/bin/$selected_distro"

		package_install_and_add_to_menu() {
		    #################################################
		    ## Handle install package and add to menu part ##
		    #################################################

		    if [[ ! -d "$TERMUX_PREFIX/share/applications/pd_added" ]]; then
		        mkdir -p "$TERMUX_PREFIX/share/applications/pd_added"
		    fi

		    # Separate options and package names
		    options=()
		    packages=()
		    for arg in "\$@"; do
		        if [[ "\$arg" == -* ]]; then
		            options+=("\$arg") # Add to options if it starts with '-'
		        else
		            packages+=("\$arg") # Add to packages otherwise
		        fi
		    done

		    # Install the packages using the package manager
		    proot-distro login "${selected_distro}" --shared-tmp -- env DISPLAY=:${display_number} sudo pacman -S"\${options[@]}" --noconfirm "\${packages[@]}"

		    # Create the packinstall.sh script
		    cat <<EOF >"${save_root_path}/packinstall.sh"
		#!/bin/bash

		source $TERMUX_PREFIX/etc/termux-desktop/common_functions
		packages=(\${packages[@]})
		EOF

		    cat <<'EOF' >>"${save_root_path}/packinstall.sh"
		for package_name in "\${packages[@]}"; do
		    desktop_files=\$(pacman -Ql \$package_name | grep -oP "/usr/share/applications/.*\.desktop$")
		    if [ -z "\$desktop_files" ]; then
		        print_failed "No .desktop files found for package \${C} \$package_name \${R}in /usr/share/applications."
		    else
		        for desktop_files_name in \$desktop_files; do
		            desktop_files_with_ext=\$(basename "\$desktop_files_name")
		            desktop_files_without_ext="\${desktop_files_with_ext%.desktop}"
		            print_success "Adding \${C}\${desktop_files_without_ext} \${G}To Termux Menu"
		            cp "/usr/share/applications/\${desktop_files_with_ext}" "$TERMUX_PREFIX/share/applications/pd_added/"
		            sed -i 's/Exec=/Exec=pdrun /g' "$TERMUX_PREFIX/share/applications/pd_added/\${desktop_files_with_ext}"
		        done
		    fi
		done
		check_and_delete 'packinstall.sh'
		EOF

		    # Execute the script with all arguments
		    proot-distro login "${selected_distro}" --shared-tmp -- /bin/bash -c "export DISPLAY=:${display_number}; export XDG_RUNTIME_DIR=${TMPDIR}; bash /root/packinstall.sh"

		    # Update icon cache and desktop database
		    gtk-update-icon-cache
		    update-desktop-database -q "$TERMUX_PREFIX/share/applications/pd_added"
		}

		package_uninstall_and_remove_from_menu() {
		    ###################################################
		    # Handle remove package and remove from menu part #
		    ###################################################

		    # Separate options and package names
		    options=()
		    packages=()
		    for arg in "\${@:2}"; do
		        if [[ "\$arg" == -* ]]; then
		            options+=("\$arg") # Add to options if it starts with '-'
		        else
		            packages+=("\$arg") # Add to packages otherwise
		        fi
		    done

		    # Create the packremove.sh script
		    cat <<EOF >"${save_root_path}/packremove.sh"
		#!/bin/bash

		source $TERMUX_PREFIX/etc/termux-desktop/common_functions
		packages=(\${packages[@]})
		EOF

		    cat <<'EOF' >>"${save_root_path}/packremove.sh"
		for package_name in "\${packages[@]}"; do
		    desktop_files=\$(pacman -Ql \$package_name | grep -oP "/usr/share/applications/.*\.desktop$")
		    if [ -z "\$desktop_files" ]; then
		        print_failed "No .desktop files found for package \${C} \$package_name \${R}in /usr/share/applications."
		    else
		        for desktop_files_name in \$desktop_files; do
		            desktop_files_with_ext=\$(basename "\$desktop_files_name")
		            desktop_files_without_ext="\${desktop_files_with_ext%.desktop}"
		            print_success "Removing \${C}\${desktop_files_without_ext} \${G}From Termux Menu"
		            check_and_delete $TERMUX_PREFIX/share/applications/pd_added/\${desktop_files_with_ext}
		        done
		    fi
		done
		check_and_delete 'packremove.sh'
		EOF

		    # Execute the script with all arguments
		    proot-distro login "${selected_distro}" --shared-tmp -- /bin/bash -c "export DISPLAY=:${display_number}; export XDG_RUNTIME_DIR=${TMPDIR}; bash /root/packremove.sh"

		    # Remove the packages using the package manager
		    proot-distro login "${selected_distro}" --shared-tmp -- env DISPLAY=:${display_number} sudo pacman -R"\${options[@]}" --noconfirm "\${packages[@]}"

		    # Update icon cache and desktop database
		    gtk-update-icon-cache
		    update-desktop-database -q "$TERMUX_PREFIX/share/applications/pd_added"
		}

		update_distro() {
		    #################################################
		    ############### Handle update part ##############
		    #################################################
		    proot-distro login --user "$final_user_name" "$selected_distro" --shared-tmp --termux-home -- env DISPLAY=:"$display_number" sudo pacman -Su
		}
	TOP_EOF
}

function chroot_distro_arch_based_app_installer() {
	cat <<-TOP_EOF >>"$TERMUX_PREFIX/bin/$selected_distro"

		package_install_and_add_to_menu() {
		    #################################################
		    ## Handle install package and add to menu part ##
		    #################################################

		    if [[ ! -d "$TERMUX_PREFIX/share/applications/pd_added" ]]; then
		        mkdir -p "$TERMUX_PREFIX/share/applications/pd_added"
		    fi

		    # Separate options and package names
		    options=()
		    packages=()
		    for arg in "\$@"; do
		        if [[ "\$arg" == -* ]]; then
		            options+=("\$arg") # Add to options if it starts with '-'
		        else
		            packages+=("\$arg") # Add to packages otherwise
		        fi
		    done

		    # Install the packages using the package manager
		    chroot-distro login "${selected_distro}" --shared-tmp -- env DISPLAY=:${display_number} sudo pacman -S"\${options[@]}" --noconfirm "\${packages[@]}"

		    # Create the packinstall.sh script
		    sudo tee "${save_root_path}/packinstall.sh" >/dev/null <<'EOF'
		#!/bin/bash

		source $TERMUX_PREFIX/etc/termux-desktop/common_functions
		packages=(\${packages[@]})
		EOF

		    cat <<'EOF' >>"${save_root_path}/packinstall.sh"
		for package_name in "\${packages[@]}"; do
		    desktop_files=\$(pacman -Ql \$package_name | grep -oP "/usr/share/applications/.*\.desktop$")
		    if [ -z "\$desktop_files" ]; then
		        print_failed "No .desktop files found for package \${C} \$package_name \${R}in /usr/share/applications."
		    else
		        for desktop_files_name in \$desktop_files; do
		            desktop_files_with_ext=\$(basename "\$desktop_files_name")
		            desktop_files_without_ext="\${desktop_files_with_ext%.desktop}"
		            print_success "Adding \${C}\${desktop_files_without_ext} \${G}To Termux Menu"
		            cp "/usr/share/applications/\${desktop_files_with_ext}" "$TERMUX_PREFIX/share/applications/pd_added/"
		            sed -i 's/Exec=/Exec=pdrun /g' "$TERMUX_PREFIX/share/applications/pd_added/\${desktop_files_with_ext}"
		        done
		    fi
		done
		check_and_delete 'packinstall.sh'
		EOF

		    # Execute the script with all arguments
		    chroot-distro login "${selected_distro}" --shared-tmp -- /bin/bash -c "export DISPLAY=:${display_number}; export XDG_RUNTIME_DIR=${TMPDIR}; bash /root/packinstall.sh"

		    # Update icon cache and desktop database
		    gtk-update-icon-cache
		    update-desktop-database -q "$TERMUX_PREFIX/share/applications/pd_added"
		}

		package_uninstall_and_remove_from_menu() {
		    ###################################################
		    # Handle remove package and remove from menu part #
		    ###################################################

		    # Separate options and package names
		    options=()
		    packages=()
		    for arg in "\${@:2}"; do
		        if [[ "\$arg" == -* ]]; then
		            options+=("\$arg") # Add to options if it starts with '-'
		        else
		            packages+=("\$arg") # Add to packages otherwise
		        fi
		    done

		    # Create the packremove.sh script
		    sudo tee "${save_root_path}/packremove.sh" >/dev/null <<'EOF'
		#!/bin/bash

		source $TERMUX_PREFIX/etc/termux-desktop/common_functions
		packages=(\${packages[@]})
		EOF

		    cat <<'EOF' >>"${save_root_path}/packremove.sh"
		for package_name in "\${packages[@]}"; do
		    desktop_files=\$(pacman -Ql \$package_name | grep -oP "/usr/share/applications/.*\.desktop$")
		    if [ -z "\$desktop_files" ]; then
		        print_failed "No .desktop files found for package \${C} \$package_name \${R}in /usr/share/applications."
		    else
		        for desktop_files_name in \$desktop_files; do
		            desktop_files_with_ext=\$(basename "\$desktop_files_name")
		            desktop_files_without_ext="\${desktop_files_with_ext%.desktop}"
		            print_success "Removing \${C}\${desktop_files_without_ext} \${G}From Termux Menu"
		            check_and_delete $TERMUX_PREFIX/share/applications/pd_added/\${desktop_files_with_ext}
		        done
		    fi
		done
		check_and_delete 'packremove.sh'
		EOF

		    # Execute the script with all arguments
		    chroot-distro login "${selected_distro}" --shared-tmp -- /bin/bash -c "export DISPLAY=:${display_number}; export XDG_RUNTIME_DIR=${TMPDIR}; bash /root/packremove.sh"

		    # Remove the packages using the package manager
		    chroot-distro login "${selected_distro}" --shared-tmp -- env DISPLAY=:${display_number} sudo pacman -R"\${options[@]}" --noconfirm "\${packages[@]}"

		    # Update icon cache and desktop database
		    gtk-update-icon-cache
		    update-desktop-database -q "$TERMUX_PREFIX/share/applications/pd_added"
		}

		update_distro() {
		    #################################################
		    ############### Handle update part ##############
		    #################################################
		    chroot-distro login --user "$final_user_name" "$selected_distro" --shared-tmp -- env DISPLAY=:"$display_number" sudo pacman -Su
		}
	TOP_EOF

}

function arch_based_app_installer() {
	if [[ "$selected_distro_type" == "chroot" ]]; then
		chroot_distro_arch_based_app_installer
	else
		proot_distro_arch_based_app_installer
	fi

}

#######################################################
################ Fedora Distro Command ################
#######################################################
function proot_distro_fedora_based_app_installer() {

	cat <<-TOP_EOF >>"$TERMUX_PREFIX/bin/$selected_distro"
		package_install_and_add_to_menu() {
		    #################################################
		    ## Handle install package and add to menu part ##
		    #################################################

		    # Create the packinstall.sh script
		    cat <<'EOF' >"${save_root_path}/packinstall.sh"
		#!/bin/bash

		source $TERMUX_PREFIX/etc/termux-desktop/common_functions

		# First ensure dnf is up to date
		sudo dnf makecache --refresh

		# Install packages - pass arguments directly
		sudo dnf install "\$@"

		# Process each argument for desktop integration
		for arg in "\$@"; do
		    # Skip options
		    if [[ "\$arg" == -* ]]; then
		        continue
		    fi
		    package_name="\$arg"

		    # Use repoquery to list desktop files for this package
		    echo "\${R}[\${C}-\${R}]\${G} Searchling for .desktop file… \${W}"
		    echo
		    desktop_files=\$(dnf repoquery --list "\$package_name" 2>/dev/null | \
		        grep "^/usr/share/applications/.*\.desktop\$" || true)

		    # If no desktop files found, try rpm -ql fallback
		    if [[ -z "\$desktop_files" ]]; then
		        desktop_files=\$(rpm -ql "\$package_name" 2>/dev/null | \
		            grep "/usr/share/applications/.*\.desktop\$" || true)
		    fi

		    if [[ -n "\$desktop_files" ]]; then
		        for desktop_path in \$desktop_files; do
		            desktop_file=\$(basename "\$desktop_path")
		            print_success "Adding \${C}\${desktop_file%.desktop} \${G}to Termux Menu"
		            cp "/usr/share/applications/\$desktop_file" "$TERMUX_PREFIX/share/applications/pd_added/"
		            sed -i 's|Exec=|Exec=pdrun |g' "$TERMUX_PREFIX/share/applications/pd_added/\$desktop_file"
		        done
		    else
		        print_failed "No .desktop files found for package \${C}\$package_name\${R} in /usr/share/applications."
		    fi
		done

		check_and_delete 'packinstall.sh'
		EOF
		    # Make the script executable
		    proot-distro login "${selected_distro}" --shared-tmp -- /bin/bash -c "chmod +x /root/packinstall.sh"
		    # Execute the script with all arguments
		    proot-distro login "${selected_distro}" --shared-tmp -- /bin/bash -c "export DISPLAY=:${display_number}; export XDG_RUNTIME_DIR=${TMPDIR}; bash /root/packinstall.sh \$*"

		    # Update icon cache and desktop database
		    gtk-update-icon-cache
		    update-desktop-database -q "$TERMUX_PREFIX/share/applications/pd_added"
		}

		package_uninstall_and_remove_from_menu() {
		    ###################################################
		    # Handle remove package and remove from menu part #
		    ###################################################
		    # Create the packremove.sh script
		    cat <<'EOF' >"${save_root_path}/packremove.sh"
		#!/bin/bash

		source $TERMUX_PREFIX/etc/termux-desktop/common_functions

		# Get the removal command (remove or autoremove)
		removal_command="\$1"
		shift

		# Process each non-option argument (package)
		for arg in "\$@"; do
		    # Skip options
		    if [[ "\$arg" == -* ]]; then
		        continue
		    fi

		    package_name="\$arg"
		    desktop_files=""

		    # Use repoquery to list desktop files for this package
		    echo "\${R}[\${C}-\${R}]\${G} Searchling for .desktop file… \${W}"
		    echo
		    desktop_files=\$(dnf repoquery --list "\$package_name" 2>/dev/null | \
		        grep "^/usr/share/applications/.*\.desktop\$" || true)

		    # If no desktop files found, try rpm -ql fallback
		    if [[ -z "\$desktop_files" ]]; then
		        desktop_files=\$(rpm -ql "\$package_name" 2>/dev/null | \
		            grep "/usr/share/applications/.*\.desktop\$" || true)
		    fi

		    # Remove the package
		    echo "\${R}[\${C}-\${R}]\${G} Removing packages...\${W}"
		    echo
		    sudo dnf remove "\$package_name"

		    # Handle desktop files
		    if [[ -z "\$desktop_files" ]]; then
		        print_failed "No .desktop files found for package \${C}\$package_name\${R} /usr/share/applications"
		    else
		        for desktop_files_name in \$desktop_files; do
		            desktop_files_with_ext=\$(basename "\$desktop_files_name")
		            desktop_files_without_ext="\${desktop_files_with_ext%.desktop}"

		            # Check if package is really uninstalled
		            if ! rpm -q "\$package_name" >/dev/null 2>&1; then
		                print_success "Removing \${C}\${desktop_files_without_ext} \${G}From Termux Menu"
		                check_and_delete "$TERMUX_PREFIX/share/applications/pd_added/\${desktop_files_with_ext}"
		            else
		                print_failed "Package \${C}\$package_name\${R} is still installed; skipping desktop removal."
		            fi
		        done
		    fi
		done

		check_and_delete 'packremove.sh'
		EOF

		    # Make the script executable
		    proot-distro login "${selected_distro}" --shared-tmp -- /bin/bash -c "chmod +x /root/packremove.sh"

		    # Execute the script with all arguments
		    proot-distro login "${selected_distro}" --shared-tmp -- /bin/bash -c "export DISPLAY=:${display_number}; export XDG_RUNTIME_DIR=$TERMUX_PREFIX/tmp; bash /root/packremove.sh \$1 \${*:2}"

		    # Update icon cache and desktop database
		    gtk-update-icon-cache
		    update-desktop-database -q "$TERMUX_PREFIX/share/applications/pd_added"
		}

		update_distro() {
		    #################################################
		    ############### Handle update part ##############
		    #################################################
		    proot-distro login --user "$final_user_name" "$selected_distro" --shared-tmp --termux-home -- env DISPLAY=:"$display_number" sudo dnf update
		}
	TOP_EOF
}

function chroot_distro_fedora_based_app_installer() {
	cat <<-TOP_EOF >>"$TERMUX_PREFIX/bin/$selected_distro"
		package_install_and_add_to_menu() {
		    #################################################
		    ## Handle install package and add to menu part ##
		    #################################################

		    # Create the packinstall.sh script
		    sudo tee "${save_root_path}/packinstall.sh" >/dev/null <<'EOF'
		#!/bin/bash

		source $TERMUX_PREFIX/etc/termux-desktop/common_functions

		# First ensure dnf is up to date
		sudo dnf makecache --refresh

		# Install packages - pass arguments directly
		sudo dnf install "\$@"

		# Process each argument for desktop integration
		for arg in "\$@"; do
		    # Skip options
		    if [[ "\$arg" == -* ]]; then
		        continue
		    fi
		    package_name="\$arg"

		    # Use repoquery to list desktop files for this package
		    echo "\${R}[\${C}-\${R}]\${G} Searchling for .desktop file… \${W}"
		    echo
		    desktop_files=\$(dnf repoquery --list "\$package_name" 2>/dev/null | \
		        grep "^/usr/share/applications/.*\.desktop\$" || true)

		    # If no desktop files found, try rpm -ql fallback
		    if [[ -z "\$desktop_files" ]]; then
		        desktop_files=\$(rpm -ql "\$package_name" 2>/dev/null | \
		            grep "/usr/share/applications/.*\.desktop\$" || true)
		    fi

		    if [[ -n "\$desktop_files" ]]; then
		        for desktop_path in \$desktop_files; do
		            desktop_file=\$(basename "\$desktop_path")
		            print_success "Adding \${C}\${desktop_file%.desktop} \${G}to Termux Menu"
		            cp "/usr/share/applications/\$desktop_file" "$TERMUX_PREFIX/share/applications/pd_added/"
		            sed -i 's|Exec=|Exec=pdrun |g' "$TERMUX_PREFIX/share/applications/pd_added/\$desktop_file"
		        done
		    else
		        print_failed "No .desktop files found for package \${C}\$package_name\${R} in /usr/share/applications."
		    fi
		done

		check_and_delete 'packinstall.sh'
		EOF
		    # Make the script executable
		    chroot-distro login "${selected_distro}" --shared-tmp -- /bin/bash -c "chmod +x /root/packinstall.sh"
		    # Execute the script with all arguments
		    chroot-distro login "${selected_distro}" --shared-tmp -- /bin/bash -c "export DISPLAY=:${display_number}; export XDG_RUNTIME_DIR=${TMPDIR}; bash /root/packinstall.sh \$*"

		    # Update icon cache and desktop database
		    gtk-update-icon-cache
		    update-desktop-database -q "$TERMUX_PREFIX/share/applications/pd_added"
		}

		package_uninstall_and_remove_from_menu() {
		    ###################################################
		    # Handle remove package and remove from menu part #
		    ###################################################
		    # Create the packremove.sh script
		    sudo tee "${save_root_path}/packremove.sh" >/dev/null <<'EOF'
		#!/bin/bash

		source $TERMUX_PREFIX/etc/termux-desktop/common_functions

		# Get the removal command (remove or autoremove)
		removal_command="\$1"
		shift

		# Process each non-option argument (package)
		for arg in "\$@"; do
		    # Skip options
		    if [[ "\$arg" == -* ]]; then
		        continue
		    fi

		    package_name="\$arg"
		    desktop_files=""

		    # Use repoquery to list desktop files for this package
		    echo "\${R}[\${C}-\${R}]\${G} Searchling for .desktop file… \${W}"
		    echo
		    desktop_files=\$(dnf repoquery --list "\$package_name" 2>/dev/null | \
		        grep "^/usr/share/applications/.*\.desktop\$" || true)

		    # If no desktop files found, try rpm -ql fallback
		    if [[ -z "\$desktop_files" ]]; then
		        desktop_files=\$(rpm -ql "\$package_name" 2>/dev/null | \
		            grep "/usr/share/applications/.*\.desktop\$" || true)
		    fi

		    # Remove the package
		    echo "\${R}[\${C}-\${R}]\${G} Removing packages...\${W}"
		    echo
		    sudo dnf remove "\$package_name"

		    # Handle desktop files
		    if [[ -z "\$desktop_files" ]]; then
		        print_failed "No .desktop files found for package \${C}\$package_name\${R} /usr/share/applications"
		    else
		        for desktop_files_name in \$desktop_files; do
		            desktop_files_with_ext=\$(basename "\$desktop_files_name")
		            desktop_files_without_ext="\${desktop_files_with_ext%.desktop}"

		            # Check if package is really uninstalled
		            if ! rpm -q "\$package_name" >/dev/null 2>&1; then
		                print_success "Removing \${C}\${desktop_files_without_ext} \${G}From Termux Menu"
		                check_and_delete "$TERMUX_PREFIX/share/applications/pd_added/\${desktop_files_with_ext}"
		            else
		                print_failed "Package \${C}\$package_name\${R} is still installed; skipping desktop removal."
		            fi
		        done
		    fi
		done

		check_and_delete 'packremove.sh'
		EOF

		    # Make the script executable
		    chroot-distro login "${selected_distro}" --shared-tmp -- /bin/bash -c "chmod +x /root/packremove.sh"

		    # Execute the script with all arguments
		    chroot-distro login "${selected_distro}" --shared-tmp -- /bin/bash -c "export DISPLAY=:${display_number}; export XDG_RUNTIME_DIR=$TERMUX_PREFIX/tmp; bash /root/packremove.sh \$1 \${*:2}"

		    # Update icon cache and desktop database
		    gtk-update-icon-cache
		    update-desktop-database -q "$TERMUX_PREFIX/share/applications/pd_added"
		}

		update_distro() {
		    #################################################
		    ############### Handle update part ##############
		    #################################################
		    chroot-distro login --user "$final_user_name" "$selected_distro" --shared-tmp -- env DISPLAY=:"$display_number" sudo dnf update
		}
	TOP_EOF

}

function fedora_based_app_installer() {
	if [[ "$selected_distro_type" == "chroot" ]]; then
		chroot_distro_fedora_based_app_installer
	else
		proot_distro_fedora_based_app_installer
	fi

}

function add_chroot_distro_function_caller() {
	cat <<-EOF >>"$TERMUX_PREFIX/bin/$selected_distro"
		remove_distro_container() {
		    confirmation_y_or_n "Do you want to remove the distro\${R}it can't be undone" ans_remove_distro
		    case \$ans_remove_distro in
		        [yY]* )
		            print_success "Continuing with answer: \$ans_remove_distro"
		            sleep 0.2
		            if ! su -c "ls '$distro_path'" >/dev/null 2>&1; then
		                chroot-distro uninstall "$selected_distro"
		                distro_file_list=(
		                    "$TERMUX_PREFIX/bin/pdrun"
		                    "$TERMUX_PREFIX/share/applications/pd_added"
		                    "$TERMUX_PREFIX/bin/add2menu"
		                    "$TERMUX_PREFIX/share/applications/add2menu.desktop"
		                    "$TERMUX_PREFIX/bin/$selected_distro"
		                )
		                for distro_file in "\${distro_file_list[@]}"; do
		                    if [[ -e "\$distro_file" ]]; then
		                        check_and_delete "\$distro_file"
		                    else
		                        print_failed "File does not exist: \$distro_file"
		                    fi
		                done
		                print_success "$selected_distro removed successfully"
		                print_to_config "distro_add_answer" "n"
		            else
		                print_failed "$selected_distro does not exist"
		            fi
		            ;;
		        [nN]* )
		            echo "\${R}[\${C}-\${R}]\${C} Skipping distro remove\${W}"
		            sleep 0.2
		            ;;
		        * )
		            print_failed "Invalid input, Please enter y or n"
		            ;;
		    esac
		}

		function help_distro_container() {
			cat <<HELP_EOF
			Usage: $selected_distro [OPTION] [ARGUMENT]

			Options:
			install <packagename>    - install packages and add them to termux desktop
			remove <packagename>     - remove packages and also remove them to termux desktop
			update                   - update the Linux distro
			-r                       - login as root
			--remove                 - complitely remove the Linux distro and delete all files and data related to it
			HELP_EOF
		}

		case \$1 in
		--root|-r)
		    chroot-distro login \$(usb_bind_args) "${selected_distro}" $termux_home_link
		    ;;
		--remove | --uninstall)
		    remove_distro_container
		    ;;
		install | in | ins)
		    shift
		    package_install_and_add_to_menu "\$@"
		    ;;
		remove | autoremove | rm)
		    command="\$1"
		    shift
		    package_uninstall_and_remove_from_menu "\$command" "\$@"
		    ;;
		update | up)
		    update_distro
		    ;;
		--help|-h)
		    help_distro_container
		    ;;
		esac
	EOF
}

function add_proot_distro_function_caller() {
	cat <<-EOF >>"$TERMUX_PREFIX/bin/$selected_distro"
		remove_distro_container() {
		    confirmation_y_or_n "Do you want to remove the distro\${R}it can't be undone" ans_remove_distro
		    case \$ans_remove_distro in
		        [yY]* )
		            print_success "Continuing with answer: \$ans_remove_distro"
		            sleep 0.2
		            if [[ -d $distro_path ]]; then
		                proot-distro remove "$selected_distro"
		                distro_file_list=(
		                    "$TERMUX_PREFIX/bin/pdrun"
		                    "$TERMUX_PREFIX/share/applications/pd_added"
		                    "$TERMUX_PREFIX/bin/add2menu"
		                    "$TERMUX_PREFIX/share/applications/add2menu.desktop"
		                    "$TERMUX_PREFIX/bin/$selected_distro"
		                )
		                for distro_file in "\${distro_file_list[@]}"; do
		                    if [[ -e "\$distro_file" ]]; then
		                        check_and_delete "\$distro_file"
		                    else
		                        print_failed "File does not exist: \$distro_file"
		                    fi
		                done
		                print_success "$selected_distro removed successfully"
		                print_to_config "distro_add_answer" "n"
		            else
		                print_failed "$selected_distro does not exist"
		            fi
		            ;;
		        [nN]* )
		            echo "\${R}[\${C}-\${R}]\${C} Skipping distro remove\${W}"
		            sleep 0.2
		            ;;
		        * )
		            print_failed "Invalid input, Please enter y or n"
		            ;;
		    esac
		}

		function help_distro_container() {
			cat <<HELP_EOF
			Usage: $selected_distro [OPTION] [ARGUMENT]

			Options:
			install <packagename>    - install packages and add them to termux desktop
			remove <packagename>     - remove packages and also remove them to termux desktop
			update                   - update the Linux distro
			-r                       - login as root
			--remove                 - complitely remove the Linux distro and delete all files and data related to it
			HELP_EOF
		}

		case \$1 in
		--root|-r)
		    proot-distro login \$(usb_bind_args) "$selected_distro" $termux_home_link
		    ;;
		--remove | --uninstall)
		    remove_distro_container
		    ;;
		install | in | ins)
		    shift
		    package_install_and_add_to_menu "\$@"
		    ;;
		remove | autoremove | rm)
		    command="\$1"
		    shift
		    package_uninstall_and_remove_from_menu "\$command" "\$@"
		    ;;
		update | up)
		    update_distro
		    ;;
		--help|-h)
		    help_distro_container
		    ;;
		esac
	EOF
}

function add_distro_function_caller() {
	if [[ "$selected_distro_type" == "chroot" ]]; then
		add_chroot_distro_function_caller
	else
		add_proot_distro_function_caller
	fi
}

function distro_create_app_installer() {
	banner
	print_msg "${BOLD}Creating distro app manager..."

	save_root_path="$distro_path/root"
	add_installer_common
	if [[ "$selected_distro" == "debian" ]] || [[ "$selected_distro" == "ubuntu" ]]; then
		debian_based_app_installer
	elif [[ "$selected_distro" == "archlinux" ]]; then
		arch_based_app_installer
	elif [[ "$selected_distro" == "fedora" ]]; then
		fedora_based_app_installer
	fi
	add_distro_function_caller
	chmod +x "$TERMUX_PREFIX/bin/$selected_distro"

}

#####################
# Add To Menu Setup #
#####################
function add_add_to_menu() {
	banner
	package_install_and_check "zenity"

	check_and_create_directory "$TERMUX_PREFIX/share/applications/pd_added"

	check_and_create_directory "$TERMUX_PREFIX/share/applications/"
	check_and_delete "$TERMUX_PREFIX/share/applications/add2menu.desktop"
	check_and_delete "$TERMUX_HOME/Desktop/add2menu.desktop"
	check_and_create_directory "$TERMUX_PREFIX/opt/add2menu"
	download_file "$TERMUX_PREFIX/opt/add2menu/add2menu.py" "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/add2menu/add2menu.py"
	download_file "$TERMUX_PREFIX/opt/add2menu/add2menu_legacy" "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/add2menu/add2menu_legacy"
	download_file "$TERMUX_PREFIX/share/applications/org.sabamdarif.termux.add2menu.desktop" "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/add2menu/org.sabamdarif.termux.add2menu.desktop"
	cp "$TERMUX_PREFIX/share/applications/org.sabamdarif.termux.add2menu.desktop" "$TERMUX_HOME/Desktop/"
	chmod +x "$TERMUX_HOME/Desktop/org.sabamdarif.termux.add2menu.desktop"
	chmod +x "$TERMUX_PREFIX/opt/add2menu/add2menu_legacy"

	cat <<-EOF >"$TERMUX_PREFIX/bin/add2menu"
		#!/data/data/com.termux/files/usr/bin/bash

		export distro_name="${selected_distro}"
		case \$1 in
		    --legacy)
		    .$TERMUX_PREFIX/opt/add2menu/add2menu_legacy
		    ;;
		    --legacy-nogpu)
		    $TERMUX_PREFIX/opt/add2menu/add2menu_legacy --nogpu
		    ;;
		    --help|-h)
				cat <<HELP_EOF
				Usage: add2menu [OPTION]

				Options:
				--legacy           - launch the old add2menu (uses zenity)
				--legacy-nogpu     - launch the old add2menu without gpu acceleration (uses zenity)
				--help, -h         - show help
				HELP_EOF
			;;
		    *)
		    python $TERMUX_PREFIX/opt/add2menu/add2menu.py
		    ;;
		esac

	EOF

	chmod +x "$TERMUX_PREFIX/bin/add2menu"
}

#########################################################################
#
# App Launcher Setup / setup the pdrun command
#
#########################################################################

function distro_app_launch_setup() {
	if [[ "$enable_hw_acc" == "y" ]]; then

		cat <<-EOF >"$TERMUX_PREFIX/bin/pdrun"
			#!/data/data/com.termux/files/usr/bin/bash

			source $TERMUX_PREFIX/etc/termux-desktop/common_functions

			usb_mounts() {
			  local candidates seen="" media uuid acc
			  candidates=\$(awk '(\$2 ~ "^/mnt/media_rw/[0-9A-Fa-f-]+\$") && (\$3 ~ /vfat|exfat|ntfs|fuseblk/) {print \$2}' /proc/mounts | sort -u)
			  while IFS= read -r media; do
			    [ -d "\$media" ] || continue
			    uuid="\${media##*/}"
			    acc="/storage/\${uuid}"; [ -r "\$acc" ] || acc="\$media"
			    [ -r "\$acc" ] || continue
			    case ",\$seen," in *",\$uuid,"*) ;; *) printf '%s\n' "\$acc"; seen="\${seen},\${uuid}";; esac
			  done <<< "\$candidates"
			}

			urldecode() { local s="\${1//+/ }"; printf '%b' "\${s//%/\\\\x}"; }

			normalize_arg() {
			  local a="\$1"
			  case "\$a" in file://*) a="\${a#file://}";; esac
			  if [[ "\$a" == *%* || "\$a" == *+* ]]; then a="\$(urldecode "\$a")"; fi
			  echo "\$a"
			}

			enum_media=0

			usb_bind_args() {
			  if [ -n "\${PDRUN_DISABLE_USB_BIND:-}" ]; then printf ''; return 0; fi

			  local args="--bind /storage:/storage --bind /mnt/media_rw:/mnt/media_rw"

			  local list; if [ -n "\${PDRUN_USB_BIND_PATH:-}" ]; then list="\${PDRUN_USB_BIND_PATH}"; else list="\$(usb_mounts 2>/dev/null)"; fi
			  if [ -n "\$list" ]; then
			    local include="\${PDRUN_USB_INCLUDE:-}"; local exclude="\${PDRUN_USB_EXCLUDE:-}"; local limit="\${PDRUN_USB_LIMIT:-0}"
			    local count=0
			    while IFS= read -r p; do
			      [ -n "\$p" ] || continue
			      local uuid="\${p##*/}"
			      if [ -n "\$include" ]; then case ",\$include," in *",\$uuid,"*) ;; *) continue;; esac; fi
			      if [ -n "\$exclude" ]; then case ",\$exclude," in *",\$uuid,"*) continue;; esac; fi
			      if [ "\$limit" -gt 0 ] && [ "\$count" -ge "\$limit" ]; then break; fi
			      args="\${args} --bind \${p}:/mnt/usb/\${uuid}"
			      count=\$((count+1))
			    done <<< "\$list"
			  fi

			  if [ "\${enum_media:-0}" -eq 1 ] || [[ "\${PDRUN_MEDIA_RW_ENUM:-}" =~ ^(1|true|yes)\$ ]]; then
			    while IFS= read -r p; do
			      [ -n "\$p" ] || continue
			      args="\${args} --bind \${p}:\${p}"
			      uuid="\${p##*/}"; st="/storage/\${uuid}"
			      [ -r "\$st" ] && args="\${args} --bind \${st}:\${st}"
			    done <<<"\$(usb_mounts 2>/dev/null | sed -E 's|^/storage/([0-9A-Fa-f-]+)\$|/mnt/media_rw/\\\\1|')"
			  fi

			  printf '%s' "\$args"
			}

			if [[ "${selected_distro_type}" == "proot" ]]; then
			# This code block is taken from:- https://github.com/termux/proot-distro/blob/master/proot-distro.sh#L172C1-L184C1
			TRACER_PID=\$(grep TracerPid "/proc/\$\$/status" | cut -d \$'\t' -f 2)
			if [ "\$TRACER_PID" != 0 ]; then
				TRACER_NAME=\$(grep Name "/proc/\${TRACER_PID}/status" | cut -d \$'\t' -f 2)
				if [ "\$TRACER_NAME" = "proot" ]; then
					msg
					print_failed "pdrun should not be executed under PRoot.\${W}"
					msg
					exit 1
				fi
				unset TRACER_NAME
			fi
			unset TRACER_PID
			fi
			selected_pd_hw_method="$pd_hw_method"
		EOF

		if [[ "$pd_useradd_answer" == "n" ]]; then
			cat <<-EOF >>"$TERMUX_PREFIX/bin/pdrun"
				xhost + > /dev/null 2>&1

				use_nogpu=false
				args=()

				while [[ \$# -gt 0 ]]; do
				  case "\$1" in
				    --nogpu)
				      use_nogpu=true
				      shift
				      ;;
				    --help|-h)
						cat <<HELP_EOF
						Usage: pdrun [--nogpu] COMMAND

						Options:
						--nogpu    - disable GPU acceleration
						HELP_EOF
						exit 0
						;;
				    *)
				      args+=("\$1")
				      shift
				      ;;
				  esac
				done

				user_arg="--user $final_user_name"

				if [ "\$use_nogpu" = true ]; then
				  gpu_env="env LIBGL_ALWAYS_SOFTWARE=1 MESA_LOADER_DRIVER_OVERRIDE=llvmpipe GALLIUM_DRIVER=llvmpipe"
				else
				  gpu_env="env $selected_pd_hw_method"
				fi

				"${selected_distro_type}"-distro login \$(usb_bind_args) \$user_arg "$selected_distro" --shared-tmp $termux_home_link -- env DISPLAY=\$(echo \$DISPLAY) XDG_RUNTIME_DIR=\${TMPDIR} \$gpu_env sh -lc 'umask 022; exec "\$@"' _ "\${args[@]}"
			EOF
		else
			cat <<-EOF >>"$TERMUX_PREFIX/bin/pdrun"
				xhost + > /dev/null 2>&1

				use_root=false
				use_nogpu=false
				args=()

				while [[ \$# -gt 0 ]]; do
				  case "\$1" in
				    --root)
				      use_root=true
				      shift
				      ;;
				    --nogpu)
				      use_nogpu=true
				      shift
				      ;;
				    --help|-h)
						cat <<HELP_EOF
						Usage: pdrun [--root] [--nogpu] COMMAND

						Options:
						--root     - run as root user
						--nogpu    - disable GPU acceleration
						HELP_EOF
						exit 0
					;;
				    *)
				      args+=("\$1")
				      shift
				      ;;
				  esac
				done

				if [ "\$use_root" = true ]; then
				  user_arg="--user root"
				else
				  user_arg="--user $final_user_name"
				fi

				if [ "\$use_nogpu" = true ]; then
				  gpu_env="env LIBGL_ALWAYS_SOFTWARE=1 MESA_LOADER_DRIVER_OVERRIDE=llvmpipe GALLIUM_DRIVER=llvmpipe"
				else
				  gpu_env="env $selected_pd_hw_method"
				fi

				"${selected_distro_type}"-distro login \$(usb_bind_args) \$user_arg "$selected_distro" --shared-tmp $termux_home_link -- env DISPLAY=\$(echo \$DISPLAY) XDG_RUNTIME_DIR=\${TMPDIR} \$gpu_env sh -lc 'umask 022; exec "\$@"' _ "\${args[@]}"
			EOF
		fi

	elif [[ "$enable_hw_acc" == "n" ]]; then

		cat <<-EOF >"$TERMUX_PREFIX/bin/pdrun"
			#!/data/data/com.termux/files/usr/bin/bash

			source $TERMUX_PREFIX/etc/termux-desktop/common_functions

			usb_mounts() {
			  local candidates seen="" media uuid acc
			  candidates=\$(awk '(\$2 ~ "^/mnt/media_rw/[0-9A-Fa-f-]+\$") && (\$3 ~ /vfat|exfat|ntfs|fuseblk/) {print \$2}' /proc/mounts | sort -u)
			  while IFS= read -r media; do
			    [ -d "\$media" ] || continue
			    uuid="\${media##*/}"
			    acc="/storage/\${uuid}"; [ -r "\$acc" ] || acc="\$media"
			    [ -r "\$acc" ] || continue
			    case ",\$seen," in *",\$uuid,"*) ;; *) printf '%s\n' "\$acc"; seen="\${seen},\${uuid}";; esac
			  done <<< "\$candidates"
			}

			urldecode() { local s="\${1//+/ }"; printf '%b' "\${s//%/\\\\x}"; }

			normalize_arg() {
			  local a="\$1"
			  case "\$a" in file://*) a="\${a#file://}";; esac
			  if [[ "\$a" == *%* || "\$a" == *+* ]]; then a="\$(urldecode "\$a")"; fi
			  echo "\$a"
			}

			enum_media=0

			usb_bind_args() {
			  if [ -n "\${PDRUN_DISABLE_USB_BIND:-}" ]; then printf ''; return 0; fi

			  local args="--bind /storage:/storage --bind /mnt/media_rw:/mnt/media_rw"

			  local list; if [ -n "\${PDRUN_USB_BIND_PATH:-}" ]; then list="\${PDRUN_USB_BIND_PATH}"; else list="\$(usb_mounts 2>/dev/null)"; fi
			  if [ -n "\$list" ]; then
			    local include="\${PDRUN_USB_INCLUDE:-}"; local exclude="\${PDRUN_USB_EXCLUDE:-}"; local limit="\${PDRUN_USB_LIMIT:-0}"
			    local count=0
			    while IFS= read -r p; do
			      [ -n "\$p" ] || continue
			      local uuid="\${p##*/}"
			      if [ -n "\$include" ]; then case ",\$include," in *",\$uuid,"*) ;; *) continue;; esac; fi
			      if [ -n "\$exclude" ]; then case ",\$exclude," in *",\$uuid,"*) continue;; esac; fi
			      if [ "\$limit" -gt 0 ] && [ "\$count" -ge "\$limit" ]; then break; fi
			      args="\${args} --bind \${p}:/mnt/usb/\${uuid}"
			      count=\$((count+1))
			    done <<< "\$list"
			  fi

			  if [ "\${enum_media:-0}" -eq 1 ] || [[ "\${PDRUN_MEDIA_RW_ENUM:-}" =~ ^(1|true|yes)\$ ]]; then
			    while IFS= read -r p; do
			      [ -n "\$p" ] || continue
			      args="\${args} --bind \${p}:\${p}"
			      uuid="\${p##*/}"; st="/storage/\${uuid}"
			      [ -r "\$st" ] && args="\${args} --bind \${st}:\${st}"
			    done <<<"\$(usb_mounts 2>/dev/null | sed -E 's|^/storage/([0-9A-Fa-f-]+)\$|/mnt/media_rw/\\\\1|')"
			  fi

			  printf '%s' "\$args"
			}

			if [[ "${selected_distro_type}" == "proot" ]]; then
			# This code block is taken from:- https://github.com/termux/proot-distro/blob/master/proot-distro.sh#L172C1-L184C1
			TRACER_PID=\$(grep TracerPid "/proc/\$\$/status" | cut -d \$'\t' -f 2)
			if [ "\$TRACER_PID" != 0 ]; then
				TRACER_NAME=\$(grep Name "/proc/\${TRACER_PID}/status" | cut -d \$'\t' -f 2)
				if [ "\$TRACER_NAME" = "proot" ]; then
					msg
					print_failed "pdrun should not be executed under PRoot.\${W}"
					msg
					exit 1
				fi
				unset TRACER_NAME
			fi
			unset TRACER_PID
			fi

		EOF

		if [[ "$pd_useradd_answer" == "n" ]]; then
			cat <<-EOF >>"$TERMUX_PREFIX/bin/pdrun"
				xhost + > /dev/null 2>&1
				case \$1 in
				--help|-h)
					echo "${G}Usage: pdrun COMMAND${NC}"
				;;
				*)
				"${selected_distro_type}"-distro login \$(usb_bind_args) --user "$final_user_name" "$selected_distro" --shared-tmp $termux_home_link -- env DISPLAY=\$(echo \$DISPLAY) XDG_RUNTIME_DIR=\${TMPDIR} sh -lc 'umask 022; exec "\$@"' _ "\$@"
				;;
				esac
			EOF
		else
			cat <<-EOF >>"$TERMUX_PREFIX/bin/pdrun"
				xhost + > /dev/null 2>&1
				case \$1 in
				--root)
				"${selected_distro_type}"-distro login \$(usb_bind_args) --user root "$selected_distro" --shared-tmp $termux_home_link -- env DISPLAY=\$(echo \$DISPLAY) XDG_RUNTIME_DIR=\${TMPDIR} sh -lc 'umask 022; exec "\$@"' _ "\${@:2}"
				;;
				--help|-h)
					cat <<HELP_EOF
					Usage: pdrun [--root] COMMAND

					Options:
					--root    - run as root user
					HELP_EOF
				;;
				*)
				"${selected_distro_type}"-distro login \$(usb_bind_args) --user "$final_user_name" "$selected_distro" --shared-tmp $termux_home_link -- env DISPLAY=\$(echo \$DISPLAY) XDG_RUNTIME_DIR=\${TMPDIR} sh -lc 'umask 022; exec "\$@"' _ "\$@"
				;;
				esac
			EOF
		fi
	fi

	chmod +x "$TERMUX_PREFIX/bin/pdrun"
}

#########################################################################
#
# Install some required packages and repos
#
#########################################################################

function add_useful_repos() {
	if [[ "$selected_distro" == "ubuntu" ]] || [[ "$selected_distro" == "debian" ]]; then
		print_msg "Adding some useful repos..."
		added_repo_list=$(
			cat <<-EOF
				# Install necessary packages without prompts
				pd_package_install_and_check "wget gpg apt-transport-https"

				# Download and store the Microsoft GPG key
				wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor | sudo tee /etc/apt/keyrings/packages.microsoft.gpg > /dev/null

				# Set correct permissions on the key
				sudo install -D -o root -g root -m 644 /etc/apt/keyrings/packages.microsoft.gpg /etc/apt/keyrings/packages.microsoft.gpg

				# Add the VS Code repository non-interactively
				echo "deb [arch=amd64,arm64,armhf signed-by=/etc/apt/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main" | sudo tee /etc/apt/sources.list.d/vscode.list > /dev/null
			EOF
			create_shell_script "$save_path/run_add_useful_repos.sh" "$added_repo_list"
			"${selected_distro_type}"-distro login "$selected_distro" -- /bin/bash -c "bash /root/run_add_useful_repos.sh"
		)
	elif [[ "$selected_distro" == "fedora" ]]; then
		print_msg "Adding some useful repos..."
		added_repo_list=$(
			cat <<-EOF
				# Import Microsoft GPG key
				rpm --import https://packages.microsoft.com/keys/microsoft.asc

				# Add the VS Code repository without user interaction
				echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com/yumrepos/vscode\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" | sudo tee /etc/yum.repos.d/vscode.repo > /dev/null

				# Update the package list
				dnf check-update -y
			EOF
			create_shell_script "$save_path/run_add_useful_repos.sh" "$added_repo_list"
			"${selected_distro_type}"-distro login "$selected_distro" -- /bin/bash -c "bash /root/run_add_useful_repos.sh"
		)
	fi
}

function install_some_required_pack() {
	local some_required_pack_list=""

	if [[ "$selected_distro" == "ubuntu" ]] || [[ "$selected_distro" == "debian" ]]; then
		# Debian/Ubuntu
		some_required_pack_list="\
zlib1g zlib1g-dev fuse xdg-utils apt-file dbus dbus-x11 \
libnss3 libgtk-3-0 libx11-xcb1 libxext6 libxrender1 libxrandr2 \
libxi6 libxtst6 libatk1.0-0 libatk-bridge2.0-0 libglib2.0-0 libglib2.0-bin \
libpango-1.0-0 libcairo2 libfreetype6 libfontconfig1 libcups2 libdbus-1-3 \
libdrm2 libgbm1 libxcomposite1 libxdamage1 libxcb-dri3-0 libxshmfence1"

	elif [[ "$selected_distro" == "fedora" ]]; then
		# Fedora (40+)
		some_required_pack_list="\
zlib-ng fuse xdg-utils dbus \
nss gtk3 alsa-lib libX11 libXext libXrender libXrandr libXi libXtst \
atk at-spi2-atk glib2 pango cairo freetype fontconfig cups-libs dbus-libs \
libdrm mesa-libgbm libXcomposite libXdamage libxcb libxshmfence"

	elif [[ "$selected_distro" == "archlinux" ]]; then
		# Arch Linux
		some_required_pack_list="\
zlib fuse2 xdg-utils dbus \
nss gtk3 alsa-lib libx11 libxext libxrender libxrandr libxi libxtst \
atk at-spi2-core glib2 pango cairo freetype2 fontconfig cups dbus \
libdrm mesa-libgbm libxcomposite libxdamage libxcb libxshmfence"
	fi
	banner
	print_msg "Installing some distro specfic required packages"
	pd_setup_some_required_pack=$(
		cat <<-EOF
			pd_package_install_and_check "$some_required_pack_list"
			check_and_delete "some_required_pack.sh"
		EOF
	)
	create_shell_script "$save_path/some_required_pack.sh" "$pd_setup_some_required_pack"
	"${selected_distro_type}"-distro login "$selected_distro" -- /bin/bash -c 'bash /root/some_required_pack.sh'
}

function install_distro_container() {
	set_distro_paths
	setup_distro
	if [[ "$selected_distro_type" == "chroot" ]]; then
		termux_home_link=" "
	else
		termux_home_link="--termux-home"
	fi
	distro_basic_task
	if [[ "$CALL_FROM_CHANGE_DISTRO" == false ]]; then
		if [[ "$enable_hw_acc" == "y" ]]; then
			hw_config
		fi
	fi
	distro_zsh_setup
	distro_terminal_utility_setup
	distro_create_app_installer
	add_add_to_menu
	add_useful_repos
	if [[ "$LITE_MODE" != "1" && "$LITE_MODE" != "true" ]]; then
		install_some_required_pack
	fi
	distro_app_launch_setup
}

#########################################################################
#
# Check Installation
#
#########################################################################

function chroot_disro_container_install_check() {
	if [[ -f "$TERMUX_PREFIX/bin/$selected_distro" ]] && su -c "ls /data/local/chroot-distro/installed-rootfs/$selected_distro" &>/dev/null; then
		echo
		print_success "${BOLD} $selected_distro container setup successfully"
	else
		max_retries=2
		retry_count=0
		while [[ "$retry_count" -lt "$max_retries" ]]; do
			print_failed "Some problem occurred in $selected_distro setup"
			echo
			print_msg "Trying again... (Attempt $((retry_count + 1)) of $max_retries)"
			install_distro_container
			if [[ -f "$TERMUX_PREFIX/bin/$selected_distro" ]] && su -c "ls /data/local/chroot-distro/installed-rootfs/$selected_distro" &>/dev/null; then
				echo
				print_success "${BOLD} $selected_distro container setup successfully"
				break
			fi
			((retry_count++))
		done

		if [[ "$retry_count" -eq "$max_retries" ]]; then
			print_failed "Failed to set up $selected_distro container after multiple attempts. Skipping...${NC}"
		fi
	fi
}

function proot_disro_container_install_check() {
	if [[ -f "$TERMUX_PREFIX/bin/$selected_distro" ]] && [[ -d "$TERMUX_PREFIX/var/lib/proot-distro/installed-rootfs/$selected_distro" ]]; then
		echo
		print_success "${BOLD} $selected_distro container setup successfully"
	else
		max_retries=2
		retry_count=0
		while [[ "$retry_count" -lt "$max_retries" ]]; do
			print_failed "Some problem occurred in $selected_distro setup"
			echo
			print_msg "Trying again... (Attempt $((retry_count + 1)) of $max_retries)"
			install_distro_container
			if [[ -f "$TERMUX_PREFIX/bin/$selected_distro" ]] && [[ -d "$TERMUX_PREFIX/var/lib/proot-distro/installed-rootfs/$selected_distro" ]]; then
				echo
				print_success "${BOLD} $selected_distro container setup successfully"
				break
			fi
			((retry_count++))
		done

		if [[ "$retry_count" -eq "$max_retries" ]]; then
			print_failed "Failed to set up $selected_distro container after multiple attempts. Skipping...${NC}"
		fi
	fi
}

function disro_container_install_check() {
	if [[ "$selected_distro_type" == "chroot" ]]; then
		chroot_disro_container_install_check
	else
		proot_disro_container_install_check
	fi
}

check_termux

# why this seperate main function ?
# -> in somepart part of the main setup script
# you just want to source all the functions
# but don't want to run the entire setup process
function run_distro_container_setup_main() {
	install_distro_container
	disro_container_install_check
}
